package com.woniuxy.flowable.controller;

import com.woniuxy.flowable.dto.RecordDto;
import com.woniuxy.flowable.dto.ResponseData;
import com.woniuxy.flowable.dto.StartFlowDto;
import com.woniuxy.flowable.service.FlowAbleService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

/**
 * Flowable工作流控制器
 * @author woniuxy
 */
@RestController
@RequestMapping({"/workflow"})
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class FlowableController {
    @Resource
    private FlowAbleService flowAbleService;
    
    @Resource
    private RepositoryService repositoryService;

    /**
     * 开启流程
     *
     * @param startFlowDto 启动流程的Dto
     * @return
     */
    @PostMapping("/startFlowAble")
    public String startFlowAble(@RequestBody StartFlowDto startFlowDto) {
        return flowAbleService.startFlowAble(startFlowDto.getXMLPath(), startFlowDto.getFlowName(), startFlowDto.getInfo(), startFlowDto.getRolesDto(), startFlowDto.getConditions());
    }
    
    /**
     * 启动流程 - 供订单服务调用
     */
    @PostMapping("/process/start")
    public ResponseData<?> startProcess(@RequestBody Map<String, Object> params) {
        try {
            String processDefinitionKey = (String) params.get("processDefinitionKey");
            String businessKey = (String) params.get("businessKey");
            Map<String, Object> variables = (Map<String, Object>) params.get("variables");
            
            // 启动流程实例
            ProcessInstance processInstance = flowAbleService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
            
            Map<String, Object> result = new HashMap<>();
            result.put("processInstanceId", processInstance.getId());
            result.put("processDefinitionId", processInstance.getProcessDefinitionId());
            result.put("businessKey", processInstance.getBusinessKey());
            
            return ResponseData.success(result);
            
        } catch (Exception e) {
            return ResponseData.error("启动流程失败: " + e.getMessage());
        }
    }

    /**
     * 查询用户待办任务
     *
     * @param userName 用户名
     * @return
     */
    @PostMapping("/queryUserFlow")
    public ResponseData<?> queryUserFlow(@RequestParam("userName") String userName) {
        return ResponseData.success(flowAbleService.queryUserFlow(userName));
    }

    /**
     * 查询用户已办任务
     *
     * @param userName 用户名
     * @return
     */
    @PostMapping("/queryCompletedTasks")
    public ResponseData<?> queryCompletedTasks(@RequestParam("userName") String userName) throws ParseException {
        return ResponseData.success(flowAbleService.queryCompletedTasks(userName));
    }

    /**
     * 通过审批
     *
     * @param taskId 任务id
     * @return
     */
    @PostMapping("/acceptFlow")
    public ResponseData<?> acceptFlow(@RequestParam("taskId") String taskId) {
        flowAbleService.acceptFlow(taskId);
        return ResponseData.success();
    }

    /**
     * 拒绝审批
     *
     * @param taskId
     * @param reason
     * @return
     */
    @PostMapping("/rejectFlow")
    public ResponseData<?> rejectFlow(@RequestParam("taskId") String taskId, @RequestParam("reason") String reason) {
        flowAbleService.rejectFlow(taskId, reason);
        return ResponseData.success();
    }

    /**
     * 测试动态审批功能
     *
     * @return
     */
    @PostMapping("/testDynamicApproval")
    public ResponseData<?> testDynamicApproval() {
        String result = flowAbleService.testDynamicApproval();
        return ResponseData.success(result);
    }
    
    /**
     * 添加用户到地区经理组
     *
     * @param userName 用户名
     * @return
     */
    @PostMapping("/addUserToDistrictManagerGroup")
    public ResponseData<?> addUserToDistrictManagerGroup(@RequestParam("userName") String userName) {
        flowAbleService.addUserToDistrictManagerGroup(userName);
        return ResponseData.success("用户已添加到地区经理组");
    }
    
    /**
     * 从地区经理组移除用户
     *
     * @param userName 用户名
     * @return
     */
    @PostMapping("/removeUserFromDistrictManagerGroup")
    public ResponseData<?> removeUserFromDistrictManagerGroup(@RequestParam("userName") String userName) {
        flowAbleService.removeUserFromDistrictManagerGroup(userName);
        return ResponseData.success("用户已从地区经理组移除");
    }
    
    /**
     * 检查用户是否有地区经理权限
     *
     * @param userName 用户名
     * @return
     */
    @PostMapping("/hasDistrictManagerPermission")
    public ResponseData<?> hasDistrictManagerPermission(@RequestParam("userName") String userName) {
        boolean hasPermission = flowAbleService.hasDistrictManagerPermission(userName);
        return ResponseData.success(hasPermission);
    }

    /**
     * 指定流程条件
     *
     * @param taskId    任务id
     * @param variables 流程条件
     * @return
     */
    @PostMapping("/completeFlow")
    public ResponseData<?> completeFlow(@RequestParam("taskId") String taskId, @RequestBody Map<String, Object> variables) {
        flowAbleService.completeFlow(taskId, variables);
        return ResponseData.success();
    }

    /**
     * 获取当前审批人
     */
    @PostMapping("/getLocalOp")
    public ResponseData<?> getAssignees(@RequestBody RecordDto rolesDto) {
        return ResponseData.success(flowAbleService.getLocalOperator(rolesDto.getDeploymentId()));
    }

    
    /**
     * 重新部署流程定义
     *
     * @return
     */
    @PostMapping("/redeployProcessDefinitions")
    public ResponseData<?> redeployProcessDefinitions() {
        try {
            // 删除现有的流程定义
            repositoryService.createDeploymentQuery().list().forEach(deployment -> 
                repositoryService.deleteDeployment(deployment.getId(), true));
            
            // 重新部署流程定义
            repositoryService.createDeployment()
                .addClasspathResource("processes/OrderApprovalProcess.bpmn20.xml")
                .deploy();
            
            return ResponseData.success("流程定义重新部署成功");
        } catch (Exception e) {
            return ResponseData.error("重新部署流程定义失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/syncUser")
    public ResponseData<?> syncUser(@RequestParam String username, 
                                   @RequestParam String realName, 
                                   @RequestParam String email, 
                                   @RequestParam String groupId) {
        try {
            return ResponseData.success(flowAbleService.syncUserToFlowable(username, realName, email, groupId));
        } catch (Exception e) {
            return ResponseData.error("同步用户失败: " + e.getMessage());
        }
    }
    
    /**
     * 直接推进流程到下一个节点
     */
    @PostMapping("/advanceProcess")
    public ResponseData<?> advanceProcess(@RequestParam String taskId) {
        try {
            flowAbleService.advanceProcessToNextStep(taskId);
            return ResponseData.success("流程推进成功");
        } catch (Exception e) {
            return ResponseData.error("流程推进失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户审批历史记录
     */
    @PostMapping("/approvalHistory")
    public ResponseData<?> getApprovalHistory(@RequestBody Map<String, Object> params) {
        try {
            return ResponseData.success(flowAbleService.getApprovalHistory(params));
        } catch (Exception e) {
            return ResponseData.error("获取审批历史失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户审批统计信息
     */
    @PostMapping("/approvalStatistics")
    public ResponseData<?> getApprovalStatistics(@RequestParam String userName) {
        try {
            return ResponseData.success(flowAbleService.getApprovalStatistics(userName));
        } catch (Exception e) {
            return ResponseData.error("获取审批统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取流程步骤
     */
    @GetMapping("/process/steps")
    public ResponseData<?> getProcessSteps(@RequestParam String processInstanceId) {
        try {
            return ResponseData.success(flowAbleService.getProcessSteps(processInstanceId));
        } catch (Exception e) {
            return ResponseData.error("获取流程步骤失败: " + e.getMessage());
        }
    }

    /**
     * 查询流程状态
     */
    @GetMapping("/process/status")
    public ResponseData<?> getProcessStatus(@RequestParam String processInstanceId) {
        try {
            return ResponseData.success(flowAbleService.getProcessStatus(processInstanceId));
        } catch (Exception e) {
            return ResponseData.error("查询流程状态失败: " + e.getMessage());
        }
    }
}